/**
 * TDS PEC 4
 * Grupo 3H2M
 *
 * El paquete <code>edu.uoc.tds.pec4.server.bbdd</code> agrupa todas las clases
 * que encapsulan los objetos de acceso a datos (DAO),para realizar el acceso
 * a datos. La base de datos es PostgreSQL.
 */
package edu.uoc.tds.pec4.server.bbdd;

import edu.uoc.tds.pec4.beans.EquipamientoDTO;
import edu.uoc.tds.pec4.common.util.Constantes;
import edu.uoc.tds.pec4.server.bbdd.exceptions.DataBaseDAOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * La clase <code>EquipamientoDAO</code> es el componente de software que suministra
 * la implementación relacionada con la gestión de equipamientos en el subsistema Mantenimiento.<br />
 * Extiende la clase <code>DataBaseDAO</code><br />
 *
 * @author	Luis Rivas Mariño
 * @version	03/12/2011
 * @since	1.00
 * @see         edu.uoc.tds.pec4.server.bbdd.exceptions.DataBaseDAOException
 */
public class EquipamientoDAO extends DataBaseDAO implements IEquipamientoDAO {

    /**
     * Declaramos los PreparedStatement de las consultas a realizar
     * 
     */
    private PreparedStatement pstmtAltaEquipamiento;
    private PreparedStatement pstmtBajaLEquipamiento;
    private PreparedStatement pstmtModificaEquipamiento;
    private PreparedStatement pstmtAltaLEquipamiento;

    /**
     * Constructor de la clase, invoca al constructor de la superclase.
     *
     * @throws  DataBaseDAOException En caso de generarse una excepción de acceso
     *          a la base de datos se dispara al nivel superior
     */
    public EquipamientoDAO() throws DataBaseDAOException {
        super();

        pstmtAltaEquipamiento = super.preparedStatement("INSERT INTO equipamiento (nombre,tipoprecio,"
                + "preciohora,preciodia) VALUES(?,?,?,?) RETURNING idequipamiento");

        pstmtBajaLEquipamiento = super.preparedStatement("UPDATE equipamiento SET inactivo=1 WHERE idequipamiento=?");

        pstmtAltaLEquipamiento = super.preparedStatement("UPDATE equipamiento SET inactivo=0 WHERE idequipamiento=?");

        pstmtModificaEquipamiento = super.preparedStatement("UPDATE equipamiento SET nombre=?, tipoprecio=?,"
                + "preciohora=?,preciodia=? WHERE idequipamiento=?");
    }

    /**
     * Realiza el alta de un equipamiento en la base de datos.
     * @return  true Si el alta se realizó satisfactoriamente
     *          false Resto de los casos
     * @throws  DataBaseDAOException En caso de generarse una excepción de acceso
     *          a la base de datos se dispara al nivel superior
     */
    @Override
    public int altaEquipamiento(EquipamientoDTO equipamiento) throws DataBaseDAOException {
        
        int id;

        if (equipamiento == null) {
            throw new DataBaseDAOException(DataBaseDAOException.EQUIPAMIENTO_NULO);
        }

        try {
            // Nueva transacción
            super.setAutoCommit(false);
            
            //Insertamos el equipamiento
            pstmtAltaEquipamiento.clearParameters();
            
            pstmtAltaEquipamiento.setString(1, equipamiento.getNomEquipamiento());
            pstmtAltaEquipamiento.setInt(2, equipamiento.getTipoPrecio());
            pstmtAltaEquipamiento.setDouble(3, equipamiento.getPrecioHora());
            pstmtAltaEquipamiento.setDouble(4, equipamiento.getPrecioDia());
            
            // Lanzamos la consulta contra la BBDD
            ResultSet objRS = pstmtAltaEquipamiento.executeQuery();

            if (!objRS.next()) {
                // Lanzamos un error avisando que la secuencia no ha devuelto valor
                throw new DataBaseDAOException(DataBaseDAOException.ERROR_OBTENER_SECUENCIA_EQUIPAMIENTO);
            }
            //Recuperamos el identificador asignado al equipamiento
            id=objRS.getInt(1);
            
            objRS.close();
            super.commit();

        } catch (SQLException SQLe) {
            super.rollback();
            throw new DataBaseDAOException(DataBaseDAOException.ERROR_ALTA_EQUIPAMIENTO
                    + Constantes.SL + SQLe.getMessage());

        } finally {
            super.setAutoCommit(true);
        }
        
        return id;
    }

    /**
     * Realiza la baja lógica de un equipamiento en la base de datos.
     * @return  true Si la baja lógica se realizó satisfactoriamente
     *          false Resto de los casos
     * @throws  DataBaseDAOException En caso de generarse una excepción de acceso
     *          a la base de datos se dispara al nivel superior
     */
    @Override
    public void bajaEquipamiento(int idEquipamiento) throws DataBaseDAOException {

        try {
            // Nueva transacción
            super.setAutoCommit(false);

            // Damos de baja lógica el equipamiento
            pstmtBajaLEquipamiento.clearParameters();
            pstmtBajaLEquipamiento.setInt(1, idEquipamiento);

            pstmtBajaLEquipamiento.execute();
            super.commit();

        } catch (SQLException SQLe) {
            super.rollback();
            throw new DataBaseDAOException(DataBaseDAOException.ERROR_BAJA_EQUIPAMIENTO
                    + Constantes.SL + SQLe.getMessage());

        } finally {
            super.setAutoCommit(true);
        }

    }

    /**
     * Realiza la activación de un equipamiento que estaba en baja lógica
     * @param idEquipamiento El identificador del equipamiento a activar
     * @throws RemoteException
     * @throws GestorMantenimientoException 
     */
    @Override
    public void activaEquipamiento(int idEquipamiento) throws DataBaseDAOException {

        try {
            // Nueva transacción
            super.setAutoCommit(false);

            // Reactivamos el equipamiento
            pstmtAltaLEquipamiento.clearParameters();
            pstmtAltaLEquipamiento.setInt(1, idEquipamiento);

            pstmtAltaLEquipamiento.execute();
            super.commit();

        } catch (SQLException SQLe) {
            super.rollback();
            throw new DataBaseDAOException(DataBaseDAOException.ERROR_ALTALOGICA_EQUIPAMIENTO
                    + Constantes.SL + SQLe.getMessage());

        } finally {
            super.setAutoCommit(true);
        }
    }

    /**
     * Realiza la consulta de un equipamiento en la base de datos.
     * @return  true Si la consulta se realizó satisfactoriamente
     *          false Resto de los casos
     * @throws  DataBaseDAOException En caso de generarse una excepción de acceso
     *          a la base de datos se dispara al nivel superior
     */
    @Override
    public EquipamientoDTO consultaEquipamiento(int idEquipamiento) throws DataBaseDAOException {

        EquipamientoDTO equipamiento = new EquipamientoDTO();

        try {
            // Nueva transacción
            super.setAutoCommit(false);
            
            //Construcción de la consulta
            String consulta = "SELECT * FROM equipamiento WHERE idequipamiento = " + idEquipamiento;

            //Ejecución de la consulta
            ResultSet rs = super.obtenerConsulta(consulta);

            //Obtención de los datos del equipamiento
            equipamiento.setIdEquipamiento(rs.getInt("idequipamiento"));
            equipamiento.setnomEquipamiento(rs.getString("nombre"));
            equipamiento.setTipoPrecio(rs.getInt("tipoprecio"));
            equipamiento.setPrecioHora(rs.getDouble("preciohora"));
            equipamiento.setPrecioDia(rs.getDouble("preciodia"));

            //Liberación de recursos
            rs.close();
            rs = null;

        } catch (SQLException SQLe) {
            throw new DataBaseDAOException(DataBaseDAOException.ERROR_CONSULTA_EQUIPAMIENTO
                    + Constantes.SL + SQLe.getMessage());
        } finally {
            super.setAutoCommit(true);
        }
        return equipamiento;
    }

    /**
     * Realiza la modidificación de un equipamiento en la base de datos.
     * @return  true Si el alta se realizó satisfactoriamente
     *          false Resto de los casos
     * @throws  DataBaseDAOException En caso de generarse una excepción de acceso
     *          a la base de datos se dispara al nivel superior
     */
    @Override
    public void modificaEquipamiento(EquipamientoDTO equipamiento) throws DataBaseDAOException {

        if (equipamiento == null) {
            throw new DataBaseDAOException(DataBaseDAOException.EQUIPAMIENTO_NULO);
        }

        try {
            // Nueva transacción
            super.setAutoCommit(false);

            // Modificamos el equipamiento
            pstmtModificaEquipamiento.clearParameters();
            pstmtModificaEquipamiento.setString(1, equipamiento.getNomEquipamiento());
            pstmtModificaEquipamiento.setInt(2, equipamiento.getTipoPrecio());
            pstmtModificaEquipamiento.setDouble(3, equipamiento.getPrecioHora());
            pstmtModificaEquipamiento.setDouble(4, equipamiento.getPrecioDia());
            pstmtModificaEquipamiento.setInt(5, equipamiento.getIdEquipamiento());

            pstmtModificaEquipamiento.execute();
            super.commit();

        } catch (SQLException SQLe) {
            super.rollback();
            throw new DataBaseDAOException(DataBaseDAOException.ERROR_MODIFICACION_EQUIPAMIENTO
                    + Constantes.SL + SQLe.getMessage());

        } finally {
            super.setAutoCommit(true);
        }
    }

    /**
     * Devuelve la lista de equipamiento existente en la base de datos
     * @return  La lista de todos los equipamientos de la aplicación
     * @throws  DataBaseDAOException En caso de generarse una excepción de acceso
     *          a la base de datos se dispara al nivel superior
     */
    public List<EquipamientoDTO> listaEquipamiento() throws DataBaseDAOException {

        List<EquipamientoDTO> equipamientos = new ArrayList<EquipamientoDTO>();

        try {
            // Nueva transacción
            super.setAutoCommit(false);
            
            //Construcción de la consulta
            String eSQL = "SELECT * FROM equipamiento ORDER BY idequipamiento";

            //Se ejecuta la consulta a la base de datos
            ResultSet rs = super.obtenerConsulta(eSQL);

            //Recorrido del ResulSet para rellenar el vector
            while (rs.next()) {
                EquipamientoDTO eqp = new EquipamientoDTO();
                eqp.setIdEquipamiento(rs.getInt("idequipamiento"));
                eqp.setnomEquipamiento(rs.getString("nombre"));
                eqp.setTipoPrecio(rs.getInt("tipoprecio"));
                eqp.setPrecioDia(rs.getDouble("preciodia"));
                eqp.setPrecioHora(rs.getDouble("preciohora"));
                eqp.setInactivo(rs.getInt("inactivo"));
                equipamientos.add(eqp);
            }

            //Se liberan recursos
            rs.close();
            rs = null;

        } catch (SQLException eqS) {
            throw new DataBaseDAOException(DataBaseDAOException.ERROR_LEER_EQUIPAMIENTOS_BBDD
                    + Constantes.SL + eqS.getMessage());
        } catch (Exception eE) {
            throw new DataBaseDAOException(DataBaseDAOException.ERROR_MAESTROS_MANTENIMIENTO_GENERAL
                    + Constantes.SL + eE.getMessage());
        }finally {
            super.setAutoCommit(true);
        }

        return equipamientos;
    }
    
    /* Llama al método de la clase padre para liberar recursos
     * @see java.lang.Object#finalize() 
     */
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
    }
}